#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

// 定义结构体
typedef struct queue_msg {
    int a;
    char b;
} queue_msg_t;

// 与hv_array不同，最好想现在这样队列里面的节点保存queue_msg_t而非queue_msg_t *
#if 1
QUEUE_DECL(queue_msg_t, MsgQueue)
#else
struct MsgQueue {
    queue_msg_t* ptr;
    size_t size;
    size_t maxsize;
    size_t _offset;
};
typedef struct MsgQueue MsgQueue;
static inline queue_msg_t* MsgQueue_data(MsgQueue* p) {
    return p->ptr + p->_offset;
}
static inline int MsgQueue_size(MsgQueue* p) {
    return p->size;
}
static inline int MsgQueue_maxsize(MsgQueue* p) {
    return p->maxsize;
}
static inline int MsgQueue_empty(MsgQueue* p) {
    return p->size == 0;
}
static inline queue_msg_t* MsgQueue_front(MsgQueue* p) {
    return p->size == 0 ? ((void*)0) : p->ptr + p->_offset;
}
static inline queue_msg_t* MsgQueue_back(MsgQueue* p) {
    return p->size == 0 ? ((void*)0) : p->ptr + p->_offset + p->size - 1;
}
static inline void MsgQueue_init(MsgQueue* p, int maxsize) {
    p->_offset = 0;
    p->size = 0;
    p->maxsize = maxsize;
    do {
        *(void**)&(p->ptr) = hv_zalloc(sizeof(queue_msg_t) * maxsize);
        ;
    } while (0);
}
static inline void MsgQueue_clear(MsgQueue* p) {
    p->_offset = 0;
    p->size = 0;
    memset(p->ptr, 0, sizeof(queue_msg_t) * p->maxsize);
}
static inline void MsgQueue_cleanup(MsgQueue* p) {
    do {
        if (p->ptr) {
            hv_free(p->ptr);
            ;
            p->ptr = ((void*)0);
        }
    } while (0);
    p->_offset = p->size = p->maxsize = 0;
}
static inline void MsgQueue_resize(MsgQueue* p, int maxsize) {
    if (maxsize == 0) maxsize = 16;
    p->ptr = (queue_msg_t*)hv_realloc(p->ptr, sizeof(queue_msg_t) * maxsize, sizeof(queue_msg_t) * p->maxsize);
    p->maxsize = maxsize;
}
static inline void MsgQueue_double_resize(MsgQueue* p) {
    MsgQueue_resize(p, p->maxsize * 2);
}
static inline void MsgQueue_push_back(MsgQueue* p, queue_msg_t* elem) {
    if (p->size == p->maxsize) {
        MsgQueue_double_resize(p);
    }
    else if (p->_offset + p->size == p->maxsize) {
        memmove(p->ptr, p->ptr + p->_offset, sizeof(queue_msg_t) * p->size);
        p->_offset = 0;
    }
    p->ptr[p->_offset + p->size] = *elem;
    p->size++;
}
static inline void MsgQueue_pop_front(MsgQueue* p) {
    ((p->size > 0) ? (void)(0) : __assert_fail("p->size > 0", "/data/hb/libhv/examples/queue_test.c", 13, __extension__ __PRETTY_FUNCTION__));
    p->size--;
    if (++p->_offset == p->maxsize) p->_offset = 0;
}
static inline void MsgQueue_pop_back(MsgQueue* p) {
    ((p->size > 0) ? (void)(0) : __assert_fail("p->size > 0", "/data/hb/libhv/examples/queue_test.c", 13, __extension__ __PRETTY_FUNCTION__));
    p->size--;
}
#endif
int main() {
    // 初始化队列
    MsgQueue my_queue;
    MsgQueue_init(&my_queue, QUEUE_INIT_SIZE);

    // 入队操作
    for (int i = 0; i < 10; i++) {
        queue_msg_t msg; // 动态分配内存
        msg.a = i;       // 设置整型值
        msg.b = 'A' + i; // 设置字符值
        printf("%d : %p\n", i, msg);
        MsgQueue_push_back(&my_queue, &msg); // 入队
    }

    // 输出队列的内容
    printf("Queue contents:\n");
    for (int i = 0; i < MsgQueue_size(&my_queue); i++) {
        queue_msg_t msg = MsgQueue_data(&my_queue)[i];
        printf("msg[%d]: a = %d, b = %c\n", i, msg.a, msg.b);
    }
    printf("\n");

    // 出队操作
    printf("Dequeuing values:\n");
    while (!MsgQueue_empty(&my_queue)) {
        queue_msg_t msg = *MsgQueue_front(&my_queue);       // 获取队头指针
        printf("Dequeued: a = %d, b = %c\n", msg.a, msg.b); // 输出值
        MsgQueue_pop_front(&my_queue);                      // 出队
    }

    // 清理队列
    MsgQueue_cleanup(&my_queue);

    return 0;
}
